package com.programmingteam.wallpaperslideshow.contentprovider;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

public class ImageProvider extends ContentProvider {
	private static final String TAG = "WallpaperSlideshow";
	public static final String AUTHORITY = "com.programmingteam.wallpaperslideshow.imageprovider";

	private static final String sDbName = "wps.db";
	private static final int sDbVersion = 12;

	private static final String TABLE_IMAGES = "IMAGES";
	private static final String TABLE_SEARCHRESULTS = "SEARCH_RESULTS";
	private static final int URI_IMAGES = 1;
	private static final int URI_SEARCHRESULTS = 2;

	private static final UriMatcher sUriMatcher;
	private static HashMap<String, String> imagesProjectionMap;
	private static HashMap<String, String> searchResultsProjectionMap;

	private DatabaseHelper dbHelper;

	/** Table Column Names */
	public static final class ImagesTable implements BaseColumns {
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_IMAGES);
		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jwei512.images";
		public static final String _ID = "_ID";
		public static final String PHOTO_ID = "PHOTO_ID";
		public static final String PHOTO_PROVIDER = "PROVIDER";
		public static final String PHOTO_FILE = "PHOTO_FILE";
		public static final String PHOTO_PAGE_URI = "PHOTO_PAGE_URI";
		public static final String PHOTO_URI = "PHOTO_URI";
		public static final String PHOTO_DESC = "PHOTO_DESC";
		public static final String PHOTO_PLACE = "PHOTO_PLACE";
	}

	/** Table Column Names */
	public static final class SearchResultsTable implements BaseColumns {
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_SEARCHRESULTS);
		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jwei512.images";
		public static final String _ID = "_ID";
		public static final String PHOTO_ID = "PHOTO_ID";
		public static final String PHOTO_PROVIDER = "PROVIDER";
		public static final String PHOTO_PAGE_URI = "PHOTO_PAGE_URI";
		public static final String PHOTO_URI = "PHOTO_URI";
		public static final String PHOTO_DESC = "PHOTO_DESC";
		public static final String PHOTO_PLACE = "PHOTO_PLACE";
	}

	private static class DatabaseHelper extends SQLiteOpenHelper {
		DatabaseHelper(Context context) {
			super(context, sDbName, null, sDbVersion);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			createImagesTable(db);
			createSearchResultsTable(db);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			switch (oldVersion) {
			case 11:
				createSearchResultsTable(db);
			}
		}

		private void createImagesTable(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE " + TABLE_IMAGES + " (" + ImagesTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
					+ ImagesTable.PHOTO_ID + " BIGINT," + ImagesTable.PHOTO_PROVIDER + " VARCHAR(255),"
					+ ImagesTable.PHOTO_FILE + " VARCHAR(255)," + ImagesTable.PHOTO_PAGE_URI + " VARCHAR(255),"
					+ ImagesTable.PHOTO_URI + " VARCHAR(255)," + ImagesTable.PHOTO_DESC + " VARCHAR(255),"
					+ ImagesTable.PHOTO_PLACE + " VARCHAR(255)" + ");");

		}

		private void createSearchResultsTable(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE " + TABLE_SEARCHRESULTS + " (" + SearchResultsTable._ID
					+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + SearchResultsTable.PHOTO_ID + " BIGINT,"
					+ SearchResultsTable.PHOTO_PROVIDER + " VARCHAR(255)," + SearchResultsTable.PHOTO_PAGE_URI
					+ " VARCHAR(255)," + SearchResultsTable.PHOTO_URI + " VARCHAR(255),"
					+ SearchResultsTable.PHOTO_DESC + " VARCHAR(255)," + SearchResultsTable.PHOTO_PLACE
					+ " VARCHAR(255)" + ");");
		}
	}

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		Log.d(TAG, "ContentProvider: Deleting image item...");
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count;

		switch (sUriMatcher.match(uri)) {
		case URI_IMAGES:
			count = db.delete(TABLE_IMAGES, where, whereArgs);
			break;
		case URI_SEARCHRESULTS:
			count = db.delete(TABLE_SEARCHRESULTS, where, whereArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		Log.d(TAG, "ContentProvider: Deleted image item, count: " + count);
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch (sUriMatcher.match(uri)) {
		case URI_IMAGES:
			return ImagesTable.CONTENT_TYPE;
		case URI_SEARCHRESULTS:
			return SearchResultsTable.CONTENT_TYPE;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	// TODO Two tables handling here!
	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {

		ContentValues values;
		SQLiteDatabase db;
		long rowId;
		Uri imageUri;

		if (initialValues != null)
			values = new ContentValues(initialValues);
		else values = new ContentValues();

		db = dbHelper.getWritableDatabase();

		switch (sUriMatcher.match(uri)) {
		case URI_IMAGES:
			rowId = db.insert(TABLE_IMAGES, ImagesTable.PHOTO_PAGE_URI, values);
			break;
		case URI_SEARCHRESULTS:
			rowId = db.insert(TABLE_SEARCHRESULTS, SearchResultsTable.PHOTO_PAGE_URI, values);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		if (rowId > 0) {
			imageUri = ContentUris.withAppendedId(ImagesTable.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(imageUri, null);
			return imageUri;
		}
		else {
			throw new SQLException("Failed to insert row into " + uri);
		}
	}

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

		switch (sUriMatcher.match(uri)) {
		case URI_IMAGES:
			qb.setTables(TABLE_IMAGES);
			qb.setProjectionMap(imagesProjectionMap);
			break;
		case URI_SEARCHRESULTS:
			qb.setTables(TABLE_SEARCHRESULTS);
			qb.setProjectionMap(searchResultsProjectionMap);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) {
		case URI_IMAGES:
			count = db.update(TABLE_IMAGES, values, where, whereArgs);
			break;
		case URI_SEARCHRESULTS:
			count = db.update(TABLE_SEARCHRESULTS, values, where, whereArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(AUTHORITY, TABLE_IMAGES, URI_IMAGES);
		sUriMatcher.addURI(AUTHORITY, TABLE_SEARCHRESULTS, URI_SEARCHRESULTS);

		imagesProjectionMap = new HashMap<String, String>();
		imagesProjectionMap.put(ImagesTable._ID, ImagesTable._ID);
		imagesProjectionMap.put(ImagesTable.PHOTO_ID, ImagesTable.PHOTO_ID);
		imagesProjectionMap.put(ImagesTable.PHOTO_PROVIDER, ImagesTable.PHOTO_PROVIDER);
		imagesProjectionMap.put(ImagesTable.PHOTO_FILE, ImagesTable.PHOTO_FILE);
		imagesProjectionMap.put(ImagesTable.PHOTO_PAGE_URI, ImagesTable.PHOTO_PAGE_URI);
		imagesProjectionMap.put(ImagesTable.PHOTO_URI, ImagesTable.PHOTO_URI);
		imagesProjectionMap.put(ImagesTable.PHOTO_DESC, ImagesTable.PHOTO_DESC);
		imagesProjectionMap.put(ImagesTable.PHOTO_PLACE, ImagesTable.PHOTO_PLACE);

		searchResultsProjectionMap = new HashMap<String, String>();
		searchResultsProjectionMap.put(SearchResultsTable._ID, ImagesTable._ID);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_ID, ImagesTable.PHOTO_ID);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_PROVIDER, ImagesTable.PHOTO_PROVIDER);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_PAGE_URI, ImagesTable.PHOTO_PAGE_URI);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_URI, ImagesTable.PHOTO_URI);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_DESC, ImagesTable.PHOTO_DESC);
		searchResultsProjectionMap.put(SearchResultsTable.PHOTO_PLACE, ImagesTable.PHOTO_PLACE);
	}
}
